home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-10 | 9.9 KB | 310 lines | [TEXT/MPS ] |
- (* Pascalized version of the C Rotating Rects graphics sample.
- 8/30/94 - dmh
- *)
-
- PROGRAM RotnRects;
-
- USES
- ToolIntf, Events, Windows, Types, GraphicsTypes, GraphicsToolbox, GraphicsMacintosh, LayoutRoutines, MathRoutines, GraphicsRoutines, FontRoutines;
-
- FUNCTION GetWindowBoundsShape:gxShape; Forward;
- PROCEDURE DoDraw(aWindow: WindowPtr); Forward;
- PROCEDURE DoInitialization(aWindow: WindowPtr); Forward;
- PROCEDURE DoDispose(aWindow: WindowPtr); Forward;
-
- PROCEDURE SetDefaultViewPort(gTheWindowsViewPort: gxViewPort); C; EXTERNAL;
-
- VAR
- gWindow: WindowPtr;
- gWindowBoundsShape: gxShape;
- gTheWindowsViewPort: gxViewPort;
- theCurs: CursHandle;
- newClient: gxGraphicsClient;
- dummyError: gxGraphicsError;
- windowQDRect: Rect;
- gTotalnumberOfRectanglesDrawn: INTEGER;
- gRectangleShape: gxShape;
- gFixedWindowBounds: gxRectangle;
- gRectangleColor: gxColor;
- gChangeShapeFill: Boolean;
-
- (*------ GetWindowBoundsShape -------------------------------------------------------------------------*)
-
- FUNCTION GetWindowBoundsShape:gxShape;
- VAR
- theRect : Rect;
- QDtopLeft: Point;
- QDbotRight: Point;
- QDGXtopLeft: gxPoint;
- QDGXbotRight: gxPoint;
- theQDGXRect: gxRectangle;
- aRectanglePointer: gxRectanglePointer;
-
- BEGIN
- (* The QuickDraw rect and points which represent the portRect of the window. *)
-
- theRect := gWindow^.portRect;
- QDtopLeft.h := theRect.left;
- QDtopLeft.v := theRect.top;
- QDbotRight.h := theRect.right;
- QDbotRight.v := theRect.bottom;
-
- (* Convert the global Quickdraw coordinates to local fixed coordinates. *)
- GXConvertQDPoint(QDtopLeft, gxViewPort (0), QDGXtopLeft);
- GXConvertQDPoint(QDbotRight, gxViewPort (0), QDGXbotRight);
-
- (* Setup the dimensions for "gWindowBoundsShape" *)
- theQDGXRect.top := QDGXtopLeft.y;
- theQDGXRect.left := QDGXtopLeft.x;
- theQDGXRect.bottom := QDGXbotRight.y;
- theQDGXRect.right := QDGXbotRight.x;
-
- GetWindowBoundsShape := gxShape (GXNewRectangle(gxRectanglePointer(@theQDGXRect)));
- END;
-
-
-
- (*------ EventLoop ------------------------------------------------------------------------------------*)
-
- FUNCTION EventLoop: Boolean;
- VAR
- whichWindow: WindowPtr;
- event: EventRecord;
- whatToReturn: Boolean;
- dummy: Boolean;
-
- BEGIN
- whatToReturn := TRUE;
- dummy := WaitNextEvent(everyEvent, event, 0, nil);
-
- case event.what OF
- updateEvt:
- BEGIN
- BeginUpdate(WindowPtr (event.message));
- SetPort(gWindow);
- DoDraw(gWindow);
- EndUpdate(WindowPtr (event.message));
- END;
-
- mouseDown:
- case (FindWindow(event.where, whichWindow)) OF
- inSysWindow:
- SystemClick(event, whichWindow);
-
- inDrag:
- DragWindow(whichWindow, event.where, screenBits.bounds);
-
- inGoAway:
- IF (TrackGoAway(whichWindow, event.where) = TRUE) THEN
- whatToReturn:= FALSE;
-
- inContent:
- IF (whichWindow <> FrontWindow) THEN
- SelectWindow(whichWindow);
- END;
- END;
-
- EventLoop := whatToReturn;
- END;
-
- (*------ DoInitialization ---------------------------------------------------------------------------------*)
- (* Set up the title and size of the window *)
-
- PROCEDURE DoInitialization(aWindow: WindowPtr);
- VAR
- windowViewPortParent: gxViewPort;
- aRectanglePointer: gxRectanglePointer;
-
- BEGIN
- gChangeShapeFill := true;
- gTotalnumberOfRectanglesDrawn := 0;
-
- (*
- Get the viewPort that is attached to the window, and set the dither of this viewPort to 4. Which
- will mean that all objects that are drawn into window will be dithered at a dither level of 4.
- *)
- windowViewPortParent := GXGetWindowViewPort(aWindow);
- GXSetViewPortDither(windowViewPortParent, 4);
-
- (* Get the bounds of the window, and create a gxRectangle that will fill the window *)
- aRectanglePointer := GXGetShapeBounds(gWindowBoundsShape, 0, gFixedWindowBounds);
- gRectangleShape := GXNewRectangle(gxRectanglePointer(@gFixedWindowBounds));
-
- (* Set up an HSV gxColor space to run the rectangles through... *)
-
- gRectangleColor.space := gxHSVSpace;
- gRectangleColor.profile := nil;
- gRectangleColor.hsv.hue := 0;
- gRectangleColor.hsv.value := $FFFF;
- gRectangleColor.hsv.saturation := $FFFF;
- END;
-
-
- (*------ DoDraw ---------------------------------------------------------------------------------------*)
-
- PROCEDURE DoDraw(aWindow: WindowPtr);
- VAR
- rectangleBoundsShape: gxRectangle;
- x: fixed;
- y: fixed;
- aRectanglePointer: gxRectanglePointer;
-
- BEGIN
- IF (gTotalnumberOfRectanglesDrawn = 110) THEN
- BEGIN
-
- (*
- Time to rebuild the gxRectangle... Dispose of the "old" rectangle, and re-create a
- rectangle that will fill the window
- *)
- GXDisposeShape(gRectangleShape);
- gRectangleShape := GXNewRectangle(gxRectanglePointer(@gFixedWindowBounds));
-
- (*
- Set the gxShapeFill type, alternate drawing the gxRectangle with a solid fill and a
- gxClosedFrameFill
- *)
- IF (gChangeShapeFill = true) THEN
- BEGIN
- SetPort (aWindow);
- EraseRect(aWindow^.portRect);
- GXSetShapeFill (gRectangleShape, gxClosedFrameFill);
- gChangeShapeFill := false;
- END
- ELSE
- gChangeShapeFill := TRUE;
-
- gTotalnumberOfRectanglesDrawn := 0;
- END;
-
- GXSetShapeColor(gRectangleShape, gxColorPointer(@gRectangleColor));
- GXDrawShape(gRectangleShape);
-
- gRectangleColor.hsv.hue := gRectangleColor.hsv.hue + $0300;
-
- (*
- // Get the new bounds of the rectangle after it has been scaled by calling GXScaleShape. Each call to GXScaleShape
- // changes the bounding shape (box) of the rectangle. Determine the center of the bounding box, pass the center
- // to the GXRotateShape call. This will have the rectagnel rotated about the center.
- *)
- aRectanglePointer := GXGetShapeBounds(gRectangleShape, 0, rectangleBoundsShape);
- x := (rectangleBoundsShape.left + rectangleBoundsShape.right ) div 2;
- y := (rectangleBoundsShape.top + rectangleBoundsShape.bottom) div 2;
-
- GXRotateShape(gRectangleShape, $00020000, x, y);
- GXScaleShape(gRectangleShape, $0000F800, $0000F800, x, y);
-
- gTotalnumberOfRectanglesDrawn := gTotalnumberOfRectanglesDrawn +1;
- END;
-
-
- (*------ DoDispose -------------------------------------------------------------------------------------*)
-
- PROCEDURE DoDispose(aWindow: WindowPtr);
- BEGIN
- (*
- // You should always dispose of your GX graphics objects before tossing your window. Why? It's generally good
- // form and this approach guarantees that everything is disposed. If you had not disposed of everything, the
- // call to DisposeWindow should dispose of the objects. If you are running the debugging version of the
- // SecretGraphics init with notices set, you will receive a notice that you had not disposed of everything.
- *)
- GXDisposeShape(gRectangleShape);
- GXDisposeShape(gWindowBoundsShape);
- DisposeWindow(aWindow);
- END;
-
- BEGIN
- (* Generic heap initialization. *)
- MaxApplZone;
- MoreMasters;
- MoreMasters;
- MoreMasters;
-
- (* Initialize the toolbox. *)
- InitGraf(@thePort);
- InitFonts;
- InitWindows;
- InitCursor;
-
- theCurs := GetCursor(watchCursor);
- SetCursor(theCurs^^);
-
- newClient := GXNewGraphicsClient(nil, 300 * 1024, 0);
-
- (*
- // After we attempted to create the graphics client, we need to determine if the call
- // succeeded. If the call did not (as in the case for all GX functions), "newClient" will
- // be NULL. If it is, we alert the user to the problem. Otherwise, we will attempted to
- // allocate the GX heap below...
- *)
- IF ( newClient <> gxGraphicsClient(0)) THEN
- BEGIN
- (*
- // Initialize the new graphics environment and create the GX heap.
- *)
- GXEnterGraphics;
-
- (*
- // Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
- // call would not succeed is if there is not enough memory. In this case, the graphics
- // error which will be posted is -27999 (out of memory). At this point, we have not
- // installed an error handler, so we check for the error number corresponding to the
- // out of memory error.
- *)
- IF ( GXGetGraphicsError(dummyError) <> -27999 ) THEN
- BEGIN
- (*
- // Create a window and attach a GX viewPort to it. By attaching the viewPort to
- // the window will make sure that when a user moves or resizes the window all of
- // the GX drawing will occur within window.
- //
- // By the way, you cannot directly manipulate the parent viewPort attached to the
- // window, you will recieve a graphics error. This viewPort can only be manipulated
- // by the GX system. If you want to manipulate a viewPort attached to a window, it
- // _must_ be a child viewPort attached to the the parent viewPort attached to the
- // window.
- *)
- SetRect(windowQDRect, 50, 50, 330, 330);
- gWindow := NewWindow(nil, windowQDRect, 'Rotating Rects', TRUE, noGrowDocProc,
- WindowPtr (-1), TRUE, 0);
-
- gTheWindowsViewPort := GXNewWindowViewPort(gWindow);
- SetDefaultViewPort(gTheWindowsViewPort);
-
- (* Get the global bounds of the window. *)
- gWindowBoundsShape := GetWindowBoundsShape;
-
- (* Create the GX shapes we are going to draw to the window. *)
- DoInitialization(gWindow);
-
- SetCursor(arrow);
-
- while (EventLoop = TRUE) do
- DoDraw(gWindow); (* loop until the window is closed *)
-
- DoDispose(gWindow);
-
- GXExitGraphics; (* Deallocate all of the default structures *)
- GXDisposeGraphicsClient(newClient);
-
- END
- ELSE BEGIN
- (*
- // Since, we can not allocate the requested size for our GX heap, we need to throw
- // away the client we created and alert the user that there is not enough memory to
- // continue.
- //
- // However, you could try to create a smaller GX heap. If you decide to try to create
- // a smaller GX heap which would meet the needs of your application, you need to
- // dispose of the client you had originally created. Why? The original client
- // contains the GX heap size requested, which was too big, therefore you need to
- // dispose of it and create a client requesting a smaller size and call GXEnterGraphics
- // and check for an error.
- *)
- GXDisposeGraphicsClient( newClient );
- DebugStr ('Unfortunately, there is not enough memory for GX, please quit an app...');
- END;
- END;
- END.
-
-